package lib.standard.f;


import android.text.TextUtils;

import com.acadsoc.base.httpretrofit.config.S;
import com.blankj.utilcode.util.EncryptUtils;
import com.blankj.utilcode.util.LogUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import androidx.annotation.NonNull;

import static com.acadsoc.base.config.S.ZERO;

/**
 * @author Lynch
 * @date 2019
 * @desc
 */
public class URLUtils {
    private final static URLUtils URL_UTILS = new URLUtils();
    private Map<String, String> paramsCommon;
    private Map<String, String> paramsCommonWithoutEncryption;

    public static URLUtils getInstance() {
        return URL_UTILS;
    }

    /**
     * @param KeyAndValues    k,v不为空，荐{@link java.util.concurrent.ConcurrentHashMap}
     * @param AndBeforeSecret 传入true则表示加密时secret前需要&
     * @return 数据加密后的KeyAndValues
     */
    @NonNull
    public static Map<String, String> addSign(@NonNull Map<String, Object> KeyAndValues, boolean... AndBeforeSecret) {
        //公共参数，参与sign加密
        Map commparams = URLUtils.getInstance().getCommonParams();
        if (commparams.isEmpty()) {
        } else {
            KeyAndValues.putAll(commparams);
        }
        Iterator iterator = KeyAndValues.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            if (entry.getValue() == null) iterator.remove();
        }
        //根据键按字母表排序键值对
        List<String> keys = getAndSortKeys(KeyAndValues);

        StringBuilder toSign = new StringBuilder();

        if (AndBeforeSecret != null && AndBeforeSecret.length > ZERO && AndBeforeSecret[ZERO]) {


            for (String key : keys) {
                // T ODO: 2019/6/6 过滤不需要加密的键值对，注意空值，"apptagid=1&password=" + asePwd + "&phone=" + asePhone + "&067823ff-5c5c-45a3-9218-af01e9f4640b" fixm e secret前无&？用以下索引方案：现方案
                if (!TextUtils.equals(key, S.AppID)) {
                    toSign.append(key.toLowerCase()).append(S.equal).append(KeyAndValues.get(key)).append(S.and); //先将key变小写
                }
            }

            toSign.append(S.secret);

        } else {


            int i = 0;
            for (String key : keys) {
                // T ODO: 2019/6/6 过滤不需要加密的键值对，注意空值，"apptagid=1&password=" + asePwd + "&phone=" + asePhone + "&067823ff-5c5c-45a3-9218-af01e9f4640b"
                if (!TextUtils.equals(key, S.AppID)) {
                    if (i == 0) {

                    } else {
                        toSign.append(S.and);
                    }
                    i++;
                    toSign.append(key.toLowerCase()).append(S.equal).append(KeyAndValues.get(key)); //先将key变小写
                }
            }

            toSign.append(S.secret);

        }

        String tobesigned = toSign.toString();
        LogUtils.e("toBeSigned：" + tobesigned);
        //公共参数，不参与sign加密
        KeyAndValues.put(S.Sign, EncryptUtils.encryptMD5ToString(tobesigned));
        KeyAndValues.put(S.AppID, S.AcadsocIESApi);

        commparams = URLUtils.getInstance().getCommonParamsWithoutEncryption();
        if (commparams.isEmpty()) {
        } else {
            KeyAndValues.putAll(commparams);
        }

        return ((Map) KeyAndValues);
    }

    @NonNull
    public static <k, v> List<k> getAndSortKeys(@NonNull Map<k, v> hashMap) {
        List list = new ArrayList();
        if (hashMap.isEmpty()) return list;
        Set<k> keySet = hashMap.keySet();
        list = new ArrayList<>(keySet);
        Collections.sort(list, (Comparator<String>) (s1, s2) -> s1.compareToIgnoreCase(s2));// FIX ME: 2019/8/6 开头忽略大小写


        return list;
    }

    @NonNull
    private Map<String, String> getCommonParams() {
        if (paramsCommon == null) {
            paramsCommon = new HashMap<>();
        }
        return paramsCommon;
    }

    @NonNull
    private Map<String, String> getCommonParamsWithoutEncryption() {
        if (paramsCommonWithoutEncryption == null) {
            paramsCommonWithoutEncryption = new HashMap<>();
        }
        return paramsCommonWithoutEncryption;
    }

}
